package com.loong.tool.secret.security.digest;

import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import com.loong.tool.secret.base.Hex;
import com.loong.tool.secret.base.UTF8;
import com.loong.tool.secret.exception.SecretVariableException;

/**
 * 信息摘要处理类
 * 
 * @author 张成轩
 */
public class Digest {

	/** 读写单元大小 */
	private static final int SIZE = 1024;

	/**
	 * 摘要算法
	 */
	public enum Algorithm {

		/** MD5算法 */
		MD5("MD5"),
		/** SHA算法 */
		SHA("SHA");

		private String value;

		private Algorithm(String value) {

			this.value = value;
		}
	}

	/** 默认加密类型 */
	private static final Algorithm DEFAULT = Algorithm.SHA;

	/**
	 * 信息摘要处理
	 * 
	 * @param str 字符串
	 * @return 摘要字符串
	 */
	public static String digest(String str) {

		return digest(str, DEFAULT);
	}

	/**
	 * 信息摘要处理
	 * 
	 * @param str 字符串
	 * @param algorithm 摘要算法
	 * @return 摘要字符串
	 */
	public static String digest(String str, Algorithm algorithm) {

		// 实例化信息摘要对象
		MessageDigest md;
		try {
			md = MessageDigest.getInstance(algorithm.value);
		} catch (NoSuchAlgorithmException e) {
			throw new SecretVariableException("Digest variable init error: " + algorithm.name());
		}
		// 摘要并进行Hex处理
		return Hex.encode(md.digest(UTF8.getBytes(str)));
	}

	/**
	 * 流摘要处理
	 * 
	 * @param is 输入流
	 * @return 摘要字符串
	 * @throws IOException IO异常
	 */
	public static String digest(InputStream is) throws IOException {

		return digest(is, DEFAULT);
	}

	/**
	 * 流摘要处理
	 * 
	 * @param is 输入流
	 * @param algorithm 摘要算法
	 * @return 摘要字符串
	 * @throws IOException IO异常
	 */
	public static String digest(InputStream is, Algorithm algorithm) throws IOException {

		// 实例化信息摘要对象
		MessageDigest md;
		try {
			md = MessageDigest.getInstance(algorithm.value);
		} catch (NoSuchAlgorithmException e) {
			throw new SecretVariableException("Digest variable init error: " + algorithm.name());
		}
		byte[] buffer = new byte[SIZE];
		int count = 0;
		while ((count = is.read(buffer)) != -1)
			md.update(buffer, 0, count);
		// 摘要并进行Hex处理
		return Hex.encode(md.digest());
	}
}
